"""
!/usr/bin/env python
-*- coding: utf-8 -*-
@Author  : MarkJia
@Site    : 
@File    : 7、字典.py
"""

# 映射，哈希表。键值对集合，python 解析器会通过键去查找值
"""
字典的定义：  键必须唯一，不能重复
    字典是无序的键值对集合
    字典用{}包围
    每个键/值对之间用 ，分隔
    各个键与值之间用 ： 分隔
    字典是动态的
"""
# 空值时
dict88 = {}
print(type(dict88), dict88)  # 结果：<class 'dict'> {}

# 键为不可变的字符串，且唯一（不能重复）。值为python支持的任意数据类型：字符串、列表、元组、集合、字典等
dict1 = {'name': 'MackJia', 'city': 'HeFei', 'age': 18}
print(type(dict1), dict1)  # 结果：<class 'dict'> {'name': 'MackJia', 'city': 'HeFei', 'age': 18}

# 构造方法
dict10 = dict([('name', 'MackJia'), ('city', 'HeFei'), ('age', 18)])
print(type(dict10), dict10)  # <class 'dict'> {'name': 'MackJia', 'city': 'HeFei', 'age': 18}

# 字典推导式
dict2 = {k: v for k, v in [('name', 'MackJia'), ('city', 'HeFei'), ('age', 18)]}
print(type(dict2), dict2)  # 结果：<class 'dict'> {'name': 'MackJia', 'city': 'HeFei', 'age': 18}

# 访问元素 ： 字典取值
# 访问存在的key
dict1 = {'name': 'MackJia', 'city': 'HeFei', 'age': 18}
print(dict1['name'])  # 结果：MackJia
print(dict1['city'])  # HeFei
print(dict1['age'])  # 18

# 访问不存在的key
print(dict1['hobby1'])  # KeyError: 'hobby1'

# 增加字典的元素 dict[key] = value
dict1['hobby'] = 'basketball'
print(dict1)  # 增加爱好：{'name': 'MackJia', 'city': 'HeFei', 'age': 18, 'hobby': 'basketball'}
# 修改字字典元素
dict1['age'] = 20
print(dict1)  # 修改年龄：{'name': 'MackJia', 'city': 'HeFei', 'age': 20, 'hobby': 'basketball'}

# 嵌套字典
dict3 = {'name': 'MackJia', 'city': 'HeFei', 'age': 18, 'hobby': 'basketball',
         'data': {'id': 28923213131, 'message': 'success', 'code': 200}}
print(dict3['data']['code'])  # 200

"""
字典常用的方法：
    keys()       ->   获取所有键
    values()     ->   获取所有值
    items()      ->   获取所有键值对
    get()        ->   获取某个键对应的值
    update()     ->   更新字典
    pop()        ->   删除某个键值对
"""

# 字典常用的方法：视图对象
"""
返回由字典键组成的一个新视图对象
    1、提供字典条目的一个动态视图，当字典发生改变时，视图也会相应的改变
    2、字典视图可以被迭代产生对应的数据，并支持成员检测  ->  in、not in 来判断某个元素是否在其中
"""
print(dict3.keys())  # dict_keys(['name', 'city', 'age', 'hobby', 'data'])
print(
    dict3.values())  # dict_values(['MackJia', 'HeFei', 18, 'basketball', {'id': 28923213131, 'message': 'success', 'code': 200}])
print(
    dict3.items())  # dict_items([('name', 'MackJia'), ('city', 'HeFei'), ('age', 18), ('hobby', 'basketball'), ('data', {'id': 28923213131, 'message': 'success', 'code': 200})])

# 将字典视图转化为列表
print(list(dict3.keys()))  # 将字典所有键转化成列表。结果：['name', 'city', 'age', 'hobby', 'data']
print(list(
    dict3.values()))  # 将字典所有值转化成列表。结果：['MackJia', 'HeFei', 18, 'basketball', {'id': 28923213131, 'message': 'success', 'code': 200}]
print(list(
    dict3.items()))  # 将键值为一组，转化成列表。结果：[('name', 'MackJia'), ('city', 'HeFei'), ('age', 18), ('hobby', 'basketball'), ('data', {'id': 28923213131, 'message': 'success', 'code': 200})]

# 遍历字典的键和值
for k in dict3.keys():
    print(k)  # 取出字典所有键：name、city、age、hobby、data

for v in dict3.values():
    print(v)  # 取出字典所有值：MackJia、HeFei、18、basketball、{'id': 28923213131, 'message': 'success', 'code': 200}

for k, v in dict1.items():
    print(f'字典中{k}键字段的值为{v}')  # 格式如：字典中name键字段的值为MackJia

# 字典的api方法
# key : 如果 key 存在于字典中，返回 key 关联的 value 。如果 key 不存在，则返回 None.永远不会担心引发 KeyError 错误
print(dict3.get('name'))  # 存在取值：MackJia
# get方法  key不存在也不会报错。返回None
print(dict3.get('iphone'))  # None

# update方法 ：更新字典的键值。若存在则覆盖更新，若不存在则添加
# 存在则覆盖更新
dict1 = {'name': 'MackJia', 'city': 'HeFei'}
dict2 = {'city': 'Xian', 'age': 18}
dict1.update(dict2)
print(dict1)  # 修改字典 {'name': 'MackJia', 'city': 'Xian', 'age': 18}
# 不存在则添加
dict3 = {'hobby': 'running'}
dict1.update(dict3)
print(dict1)  # {'name': 'MackJia', 'city': 'Xian', 'age': 18, 'hobby': 'running'}

# 删除pop()   若key存在则删除该键对应的值。不存在会报错
# 已经存在的 key
dict1 = {'name': 'MackJia', 'city': 'HeFei'}
data = dict1.pop('name')
print(data)  # 返回删除的值MackJia
print(dict1)  # 返回删除后的值：{'city': 'HeFei'}
# 不存在的 key
dict1.pop('hobby')  # KeyError: 'hobby'

# 字典推导式 ； 可以从任何以键值对作为元素的可迭代对象中构建出字典
dict2 = {k: v for k, v in [('name', 'MackJia'), ('city', 'HeFei'), ('age', 18)]}
print(type(dict2), dict2)  # 结果：<class 'dict'> {'name': 'MackJia', 'city': 'HeFei', 'age': 18}

dict8 = {'a': 1, 'b': 2, 'c': 3}
# 键值对的视图对象结果 ： dict_items([('a', 1), ('b', 2), ('c', 3)])
print(dict8.items())

"""
结果：
a 1
b 2
c 3
"""
for k, v in dict8.items():
    print(k, v)

data = dict()
for k, v in dict8.items():
    data[k] = v ** 2
print(data)  # {'a': 1, 'b': 4, 'c': 9}

data3 = {k: v for k, v in dict8.items()}
print(data3)  # {'a': 1, 'b': 2, 'c': 3}

data1 = {k: v ** 2 for k, v in dict8.items() if v > 1}
print(data1)  # {'b': 4, 'c': 9}

data1 = {v: k for k, v in dict8.items()}
print(data1)  # {1: 'a', 2: 'b', 3: 'c'}
